package main

/*
(1) index
curl -i http://localhost:9999/index
HTTP/1.1 200 OK
Date: Sun, 01 Sep 2019 08:12:23 GMT
Content-Length: 19
Content-Type: text/html; charset=utf-8
<h1>Index Page</h1>

(2) v1
$ curl -i http://localhost:9999/v1/
HTTP/1.1 200 OK
Date: Mon, 12 Aug 2019 18:11:07 GMT
Content-Length: 18
Content-Type: text/html; charset=utf-8
<h1>Hello Gee</h1>

(3)
$ curl "http://localhost:9999/v1/hello?name=geektutu"
hello geektutu, you're at /v1/hello

(4)
$ curl "http://localhost:9999/v2/hello/name"
hello name, you're at /hello/name

(5)
$ curl "http://localhost:9999/v2/login" -X POST -d 'username=geektutu&password=1234'
{"password":"1234","username":"geektutu"}

(6)
$ curl "http://localhost:9999/hello"
404 NOT FOUND: /hello
*/

import (
	"net/http"

	"gee"
)

// 为了让路由更加灵活，我们将路由分组的功能也加入到框架中，分组可以为路由提供共享的前缀或者后缀，也可以将一组路由从应用中分离出来，方便控制路由组的中间件。
// 例如，我们可以为不同的路由组应用不同的中间件，这样就可以为不同的路由组应用不同的鉴权策略，或者应用不同的日志处理逻辑。
// 为了实现路由分组，我们需要将路由器router和分组routerGroup两个结构体进行重构，使得它们都具有共同的接口，这样就可以将路由组和路由器统一起来。
// 为了实现这个目标，我们将路由器router和分组routerGroup都嵌入到了engine中，这样engine就具有了路由器和分组的所有能力。

// 中间件可以给框架提供无限的扩展能力，应用在分组上，可以使得分组控制的收益更为明显，而不是共享相同的路由前缀这么简单。
// 例如/admin的分组，可以应用鉴权中间件；/分组应用日志中间件，/是默认的最顶层的分组，也就意味着给所有的路由，即整个框架增加了记录日志的能力。
func main() {
	engine := gee.New()
	// 注册
	engine.GET("/index", func(c *gee.Context) {
		c.HTML(http.StatusOK, "<h1>Index Page</h1>")
	})

	v1 := engine.Group("/v1")
	{
		v1.GET("/", func(c *gee.Context) { c.HTML(http.StatusOK, "<h1>Hello Gee</h1>") })

		v1.GET("/hello", func(c *gee.Context) {
			// expect /hello?name=geektutu
			c.String(http.StatusOK, "hello %s, you're at %s\n", c.Query("name"), c.Path)
		})
	}
	v2 := engine.Group("/v2")
	{
		v2.GET("/hello/:name", func(c *gee.Context) {
			c.String(http.StatusOK, "解析后参数： %s, 你在访问 %s\n", c.Param("name"), c.Path)
		})
		v2.POST("/login", func(c *gee.Context) {
			c.JSON(http.StatusOK, gee.H{
				"username": c.PostForm("username"),
				"password": c.PostForm("password"),
			})
		})
	}

	if err := engine.Run(":9999"); err != nil {
		return
	}
}
